using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using SpaceShooter.Components;
using SpaceShooter.Utilities;

using System.Diagnostics;

namespace SpaceShooter.StateManagement
{
    public class SavedMatch
    {
        static string filename = "savedmatch.xml";

        public static void Save(GameState gs)
        {
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            if(storage.FileExists(filename))
                storage.DeleteFile(filename);
            IsolatedStorageFileStream stream = storage.CreateFile(filename);
            XmlSerializer xml = new XmlSerializer(typeof(Match));
            Match match = new Match();
            match.setMatch(gs);
            xml.Serialize(stream, match); 
            stream.Close();
            stream.Dispose();
        }

        public static Match Load()
        {
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication(); 
            Match match;
            if (storage.FileExists(filename))
            {
                IsolatedStorageFileStream stream = storage.OpenFile(filename, FileMode.Open);
                XmlSerializer xml = new XmlSerializer(typeof(Match));
                Debug.WriteLine("STARTING DESERIALIZING...");
                match = xml.Deserialize(stream) as Match;
                Debug.WriteLine("...DESERIALIZED");
                stream.Close(); 
                stream.Dispose();
            }
            else
            {
                match = null;
            }
            return match;
        }

        public static bool SavedMatchExists()
        {
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            return storage.FileExists(filename);
        }

        public static void Delete()
        {
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            if (storage.FileExists(filename))
                storage.DeleteFile(filename);
        }
    }

    public class Match
    {
        public AsteroidsManagerComponent.Asteroid[] asteroids;
        public BulletsManagerComponent.Bullet[] enemiesBullets;
        public BulletsManagerComponent.Bullet[] playerBullets;
        public EffectManagerComponent.Explosion[] explosions;
        public EffectManagerComponent.Rock[] rocks;
        public EffectManagerComponent.Smoke[] smokes;
        public EnemyManagerComponent.Enemy[] enemies;
        public PowerUpManager.PowerUp[] powerUps;
        public PlayerComponent.PlayerState[] playerStates;
        public AsteroidsManagerComponent.AsteroidState[][] asteroidStates;
        public BulletsManagerComponent.BulletState[][] enemiesBulletsStates;
        public BulletsManagerComponent.BulletState[][] playerBulletsStates;
        public EffectManagerComponent.ExplosionState[][] explosionsStates;
        public EffectManagerComponent.RockState[][] rocksStates;
        public EffectManagerComponent.SmokeState[][] smokesStates;
        public EnemyManagerComponent.EnemyState[][] enemiesStates;
        public PowerUpManager.PowerUpState[][] powerUpsStates;
        public int levelPosition;
        public int levelFramesWaited;
        public bool endLevel;
        public Vector2 playerPosition;
        public bool timeTraveling = false;
        public int timeTank = 132;
        public int playerLife = 100;
        public LifeState playerLifeState = LifeState.NORMAL;
        public bool toggleGun = true;

        public void setMatch(GameState gs)
        {
            asteroids = gs.asteroids.ToArray();
            enemiesBullets = gs.enemiesBullets.ToArray();
            enemies = gs.enemies.ToArray();
            playerBullets = gs.playerBullets.ToArray();
            explosions = gs.explosions.ToArray();
            rocks = gs.rocks.ToArray();
            smokes = gs.smokes.ToArray();
            powerUps = gs.powerUps.ToArray();
            playerStates = gs.playerStates.ToArray();
            asteroidStates = new AsteroidsManagerComponent.AsteroidState[asteroids.Length][];
            enemiesBulletsStates = new BulletsManagerComponent.BulletState[enemiesBullets.Length][];
            enemiesStates = new EnemyManagerComponent.EnemyState[enemies.Length][];
            playerBulletsStates = new BulletsManagerComponent.BulletState[playerBullets.Length][];
            explosionsStates = new EffectManagerComponent.ExplosionState[explosions.Length][];
            rocksStates = new EffectManagerComponent.RockState[rocks.Length][];
            smokesStates = new EffectManagerComponent.SmokeState[smokes.Length][];
            powerUpsStates = new PowerUpManager.PowerUpState[powerUps.Length][];
            levelPosition = gs.levelPosition;
            levelFramesWaited = gs.levelFramesWaited;
            endLevel = gs.endLevel;
            playerPosition = gs.playerPosition;
            timeTraveling = gs.timeTraveling;
            timeTank = gs.timeTank;
            playerLife = gs.playerLife;
            playerLifeState = gs.playerLifeState;
            toggleGun = gs.toggleGun;

            for (int i = 0; i < asteroids.Length; i++)
            {
                asteroidStates[i] = asteroids[i].GetStates().ToArray();
            }
            for (int i = 0; i < enemiesBullets.Length; i++)
            {
                enemiesBulletsStates[i] = enemiesBullets[i].GetStates().ToArray();
            }
            for (int i = 0; i < enemies.Length; i++)
            {
                enemiesStates[i] = enemies[i].GetStates().ToArray();
            }
            for (int i = 0; i < explosions.Length; i++)
            {
                explosionsStates[i] = explosions[i].GetStates().ToArray();
            }
            for (int i = 0; i < rocks.Length; i++)
            {
                rocksStates[i] = rocks[i].GetStates().ToArray();
            }
            for (int i = 0; i < smokes.Length; i++)
            {
                smokesStates[i] = smokes[i].GetStates().ToArray();
            }
            for (int i = 0; i < powerUps.Length; i++)
            {
                powerUpsStates[i] = powerUps[i].GetStates().ToArray();
            }
            for (int i = 0; i < playerBullets.Length; i++)
            {
                playerBulletsStates[i] = playerBullets[i].GetStates().ToArray();
            }
        }

        public void Restore(GameState gs)
        {
            gs.asteroids = new LinkedList<AsteroidsManagerComponent.Asteroid>(asteroids);
            gs.enemiesBullets = new LinkedList<BulletsManagerComponent.Bullet>(enemiesBullets);
            gs.playerBullets = new LinkedList<BulletsManagerComponent.Bullet>(playerBullets);
            gs.explosions = new LinkedList<EffectManagerComponent.Explosion>(explosions);
            gs.rocks = new LinkedList<EffectManagerComponent.Rock>(rocks);
            gs.smokes = new LinkedList<EffectManagerComponent.Smoke>(smokes);
            gs.enemies = new LinkedList<EnemyManagerComponent.Enemy>(enemies);
            gs.powerUps = new LinkedList<PowerUpManager.PowerUp>(powerUps);
            gs.playerStates = new LinkedList<PlayerComponent.PlayerState>(playerStates);
            gs.levelPosition = levelPosition;
            gs.levelFramesWaited = levelFramesWaited;
            gs.pause = true;
            gs.endLevel = endLevel;
            gs.playerPosition = playerPosition;
            gs.timeTraveling = timeTraveling;
            gs.timeTank = timeTank;
            gs.playerLife = playerLife;
            gs.playerLifeState = playerLifeState;
            gs.toggleGun = toggleGun;

            for (int i = 0; i < asteroids.Length; i++)
            {
                asteroids[i].SetStates(asteroidStates[i]);
            }
            for (int i = 0; i < enemiesBullets.Length; i++)
            {
                enemiesBullets[i].SetStates(enemiesBulletsStates[i]);
            }
            for (int i = 0; i < enemies.Length; i++)
            {
                enemies[i].SetStates(enemiesStates[i]);
                enemies[i].SetWeapon();
            }
            for (int i = 0; i < explosions.Length; i++)
            {
                explosions[i].SetStates(explosionsStates[i]);
            }
            for (int i = 0; i < rocks.Length; i++)
            {
                rocks[i].SetStates(rocksStates[i]);
            }
            for (int i = 0; i < smokes.Length; i++)
            {
                smokes[i].SetStates(smokesStates[i]);
            }
            for (int i = 0; i < powerUps.Length; i++)
            {
                powerUps[i].SetStates(powerUpsStates[i]);
            }
            for (int i = 0; i < playerBullets.Length; i++)
            {
                playerBullets[i].SetStates(playerBulletsStates[i]);
            }
        }
    }
}
